package org.zhq.core;

import java.io.Closeable;
import java.nio.channels.SocketChannel;

/**
 * IoProvider的抽象
 * 提供注册输入、输出,取消注册输入、输出的方法
 *
 * @author zhengquan
 * @date 2019/1/24
 */
public interface IoProvider extends Closeable {
    void register(HandleProviderCallback callback) throws Exception;

    void unregister(SocketChannel channel);

    /**
     * 处理输出回调
     */
    abstract class HandleProviderCallback extends IoTask implements Runnable {

        private final IoProvider ioProvider;

        protected volatile IoArgs attach;

        public HandleProviderCallback(SocketChannel channel, int ops, IoProvider ioProvider) {
            super(channel, ops);
            this.ioProvider = ioProvider;
        }

        @Override
        public void run() {
            final IoArgs attach = this.attach;
            this.attach = null;
            if (onProviderTo(attach)) {
                try {
                    ioProvider.register(this);
                } catch (Exception e) {
                    fireThrowable(e);
                }
            }
        }

        @Override
        public final boolean onProcessTo() {
            final IoArgs attach = this.attach;
            this.attach = null;
            return onProviderTo(attach);
        }

        protected abstract boolean onProviderTo(IoArgs args);

        public void checkAttachNull() {
            if (attach != null) {
                throw new IllegalStateException("当前attach缓存应该为空");
            }
        }
    }
}
